﻿using DevExpress.XtraEditors;
using SerialPortHelperLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace XChipTool.Full
{
    public partial class XChip_Clock : DevExpress.XtraEditors.XtraUserControl
    {
        //记录是否使用USB设备读写
        public bool IsUsbOpen = false;
        //记录是否使用I2C设备读写
        public bool m_open = false;

        private bool isWrite = false;
        private bool isRead = false;
        public SerialPort sPortTemp;
        private static XChip_Clock _instance;
        public static XChip_Clock Instance(SerialPort _sPortTemp)
        {
            if (_instance == null)
            {
                _instance = new XChip_Clock(_sPortTemp);
            }
            return _instance;
        }
        public XChip_Clock()
        {
            InitializeComponent();
        }
        public XChip_Clock(SerialPort _sPortTemp)
        {
            sPortTemp = _sPortTemp;
            InitializeComponent();
        }

        private void simpleButton8_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(YCLK.Text))
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请输入YCLK值！", string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None);
                return;
            }
            Value0.Text = SerialSend.ReadRegister(Convert.ToUInt32(Reg0.Text,16),sPortTemp).ToString("X2");
            Value1.Text = SerialSend.ReadRegister(Convert.ToUInt32(Reg1.Text, 16), sPortTemp).ToString("X2");
            Value2.Text = SerialSend.ReadRegister(Convert.ToUInt32(Reg2.Text, 16), sPortTemp).ToString("X2");
            Value3.Text = SerialSend.ReadRegister(Convert.ToUInt32(Reg3.Text, 16), sPortTemp).ToString("X2");
            ByValue0.Text = HexToBinaryString(Value0.Text);
            ByValue1.Text = HexToBinaryString(Value1.Text);
            ByValue2.Text = HexToBinaryString(Value2.Text);
            ByValue3.Text = HexToBinaryString(Value3.Text);
            int pre_div = Convert.ToInt32(ByValue0.Text.Substring(0, 3), 2) + 1;
            int vco_loop_divider = 129 - (Convert.ToInt32(Value1.Text, 16) % 128);
            int vco_loop_divf = 0;
            if (Convert.ToInt32(ByValue2.Text.Substring(ByValue2.Text.Length - 2), 2) == 0)
            {
                vco_loop_divf = 1;
            }
            else
            {
                vco_loop_divf = (int)Math.Pow(2, Convert.ToInt32(ByValue2.Text.Substring(ByValue2.Text.Length - 2), 2) - 1);
            }
            int fvco = Convert.ToInt32(YCLK.Text,10) / pre_div * vco_loop_divider * vco_loop_divf;
            FVCO.Text = fvco.ToString();

            int FVCO7_4 = ConvertBinaryToDecimal(ByValue2.Text.Length >= 4 ? ByValue2.Text.Substring(0, 4) : ByValue2.Text) + 1;
            int FVCO3_0 = ConvertBinaryToDecimal(ByValue3.Text.Length >= 3 ? ByValue3.Text.Substring(ByValue3.Text.Length - 3) : "0") + 1;
            int MIPI_Rate7_4 = ConvertBinaryToDecimal(ByValue3.Text.Length >= 4 ? ByValue3.Text.Substring(0, 4) : ByValue3.Text) + 1;
            PLL_CLK.Text = (Convert.ToInt32(FVCO.Text, 10) / FVCO7_4).ToString();
            MIPI_Rate.Text = (Convert.ToInt32(FVCO.Text, 10) / FVCO3_0).ToString();
            PLL2_CLK.Text = (Convert.ToInt32(MIPI_Rate.Text, 10) / MIPI_Rate7_4).ToString();


            for (int i = 0; i <= 30; i++)
            {
                var addr = this.Controls.Find("addr"+ i, true);
                var addrValue = this.Controls.Find("addrValue" + i, true);
                var addrByValue = this.Controls.Find("addrByValue" + i, true);
                addrValue[0].Text = SerialSend.ReadRegister(Convert.ToUInt32(addr[0].Text, 16), sPortTemp).ToString("X2");
                addrByValue[0].Text = HexToBinaryString(addrValue[0].Text);

            }
            //0-11的divsourcesel
            for (int i = 0; i <= 14; i++)
            {
                var divsourcesel = this.Controls.Find("divsourcesel" + i, true);
                var addrByValue = this.Controls.Find("addrByValue" + (i * 2 + 1), true);
                var divsourceselval = this.Controls.Find("divsourceselval" + i, true);
                var div = this.Controls.Find("div" + i, true);
                var addrValue = this.Controls.Find("addrValue" + (i * 2), true);
                var divval = this.Controls.Find("divval" + i , true);
                var Clkval = this.Controls.Find("Clkval" + i, true);
                var val = ConvertBinaryToDecimal(addrByValue[0].Text.Substring(addrByValue[0].Text.Length - 2));
                switch (val)
                {
                    case 0:
                        divsourcesel[0].Text = "YCLK";
                        divsourceselval[0].Text = YCLK.Text;
                        divval[0].Text = "YCLK";
                        Clkval[0].Text = YCLK.Text;
                        break;
                    case 1:
                        divsourcesel[0].Text = "PLL_CLK";
                        divsourceselval[0].Text = PLL_CLK.Text;
                        divval[0].Text = (Convert.ToInt32(divsourceselval[0].Text, 10) / Convert.ToInt32(addrValue[0].Text, 10)).ToString();
                        Clkval[0].Text = divval[0].Text;
                        break;
                    default:
                        divsourcesel[0].Text = "PLL2_CLK";
                        divsourceselval[0].Text = PLL2_CLK.Text;
                        divval[0].Text = (Convert.ToInt32(divsourceselval[0].Text, 10) / Convert.ToInt32(addrValue[0].Text, 10)).ToString();
                        Clkval[0].Text = divval[0].Text;
                        break; 
                }
                div[0].Text = "/" + Convert.ToInt32(addrValue[0].Text, 16).ToString();

            }

        }

        //16进制转二进制
        public static string HexToBinaryString(string hex)
        {
            StringBuilder binaryString = new StringBuilder();

            foreach (char c in hex)
            {
                // 将16进制字符转换为二进制字符串，并确保长度为4  
                string binary = Convert.ToString((c - (c <= '9' ? '0' : 'A' - 10)), 2).PadLeft(4, '0');
                binaryString.Append(binary);
            }
            return binaryString.ToString();
        }
        // 将2进制字符串转换为十进制整数 
        static int ConvertBinaryToDecimal(string binary)
        {
            int decimalValue = 0;
            foreach (char c in binary)
            {
                if (c != '0' && c != '1')
                {
                    throw new ArgumentException("Binary string contains invalid characters.");
                }
                decimalValue = (decimalValue << 1) + (c - '0'); 
            }
            return decimalValue;
        }
    }
}
